初学redis分页缓存方法实现 |
您所在的位置:网站首页 › redis分页查询 node › 初学redis分页缓存方法实现 |
初学redis分页缓存方法实现
使用缓存技术一般是在不经常增删改查的数据,我们可以使用缓存技术将第一次请求访问的数据缓存到redis中保存起来,后来的请求的时候首先查询redis数据库是否查询到这些数据,如果存在,则返回数据,如果不存在,则到mysql或其他数据库查询数据返回并保存到redis数据库中。 为什么要采用分页缓存?直接设置缓存,如果数据量大,操作增删改,更新缓存频率高效率低。分页缓存,通过页码设置缓存,可以提高性能。(但是其实不是很好)。 缓存的时候需要考虑的一些问题: 1.新增--删除最后一页缓存(如果倒叙排序,插入数据,第一页改变,后续页列表也都改变,需要删除所有缓存)。 2.修改--更新当前页缓存。 3.删除--更新当前页以及当前页以后的页面的缓存。 上面是分页缓存实现的时候要考虑的一些问题,而我在下面实现的代码并不是这样的,因为我懒得传当前页面cuePage了在add、delete、update的时候,所以,我选择了在add、delete、update的时候都把缓存的分页缓存相关key请理了,更新了分页缓存数据。 @RequestMapping({"/","index"}) public String index(Model model, @RequestParam(value = "curPage",required = false,defaultValue ="1") Integer curPage){ //每页展示10条数据 int pageSize = 5; //总数 int totalRows = userService.getUserByTotal(); //计算分页 int totalPages = totalRows / pageSize; //可能有余页 int left = totalRows % pageSize; if (left > 0){ totalPages = totalPages + 1; } if (curPage totalPages ){ curPage = totalPages; } //计算查询的开始行 int startRow = (curPage - 1) * pageSize; Map paramMap = new ConcurrentHashMap(); paramMap.put("startRow",startRow); paramMap.put("pageSize",pageSize); paramMap.put("curPage",curPage);//第几页 List userList = userService.getUserBypage(paramMap); System.out.println("curPage:"+curPage); model.addAttribute("userList",userList); model.addAttribute("curPage",curPage); model.addAttribute("totalPages",totalPages); //跳转到模板页面 return "index"; }实现类,缓存总页数。 @Override public int getUserByTotal() { System.out.println("test:"+userMapper.selectUserByTotal()); //设置key的序列化方式,采用字符串方式,提高可读性 redisTemplate.setKeySerializer(new StringRedisSerializer()); //先从Redis缓存查询 Integer totalRows = (Integer) redisTemplate.opsForValue().get("totalRows"); if (null == totalRows){ synchronized (this){ totalRows = (Integer) redisTemplate.opsForValue().get("totalRows"); if (null == totalRows){ //去mysql数据库查询总数,并保存到redis缓存中 totalRows = userMapper.selectUserByTotal(); redisTemplate.opsForValue().set("totalRows",totalRows); System.out.println("从mysql数据库获取totalRows"); } } } return totalRows; }查询分页缓存,按照查询当前页进行缓存。缓存在redis数据库中的key="curPage1"、key="curPage2"、key="curPage3"、key="curPage*"。 @Autowired private UserMapper userMapper; @Autowired private RedisTemplate redisTemplate; @Override public List getUserBypage(Map paramMap) { //设置key的序列化方式,采用字符串方式,提高可读性 redisTemplate.setKeySerializer(new StringRedisSerializer()); Integer curPage = (Integer) paramMap.get("curPage"); List userList = (List) redisTemplate.opsForValue().get("curPage"+String.valueOf(curPage)); if (null == userList){ userList = userMapper.selectUserBypage(paramMap); redisTemplate.opsForValue().set("curPage"+String.valueOf(curPage),userList); System.out.println("从mysql数据库获取userList"); } return userList; }add。添加成功后,mysql数据库+1,redis缓存数据库需要更新一下数据总数的缓存,mysql数据库数据改变了,之前的redis中的分页缓存就不能用了,则在这里删除分页缓存,等下次最新请求访问后先查询mysql,再保存到redsi中。 @Override public int addUser(User user) { //设置key的序列化方式,采用字符串方式,提高可读性 redisTemplate.setKeySerializer(new StringRedisSerializer()); int add = userMapper.insertSelective(user); if (add > 0){ //添加成功后,mysql数据库+1,redis缓存数据库需要更新一下数据 int totalRows = userMapper.selectUserByTotal(); redisTemplate.opsForValue().set("totalRows",totalRows); //更新缓存 Set keys = redisTemplate.keys("curPage"+"*"); redisTemplate.delete(keys); } return add; }delete。删除成功后,mysql数据库-1,redis缓存数据库需要更新一下数据总数的缓存,mysql数据库数据改变了,之前的redis中的分页缓存就不能用了,则在这里删除分页缓存,等下次最新请求访问后先查询mysql,再保存到redsi中。 @Override public int deleteUser(Integer id) { //设置key的序列化方式,采用字符串方式,提高可读性 redisTemplate.setKeySerializer(new StringRedisSerializer()); int delete = userMapper.deleteByPrimaryKey(id); if (delete > 0){ //删除成功后,mysql数据库-1,redis缓存数据库需要更新一下数据 int totalRows = userMapper.selectUserByTotal(); redisTemplate.opsForValue().set("totalRows",totalRows); //更新缓存 Set keys = redisTemplate.keys("curPage"+"*"); redisTemplate.delete(keys); } return delete; }update。update后mysql数据库数据改变了,之前的redis中的分页缓存就不能用了,则在这里删除分页缓存,等下次最新请求访问后先查询mysql,再保存到redsi中。 @Override public int updateUser(User user) { //设置key的序列化方式,采用字符串方式,提高可读性 redisTemplate.setKeySerializer(new StringRedisSerializer()); //boolean b = redisTemplate.delete("curPage"+"*");// Set keys = redisTemplate.keys("curPage"+"*"); redisTemplate.delete(keys); return userMapper.updateByPrimaryKey(user); }redisTemplate模糊匹配删除 Set keys = redisTemplate.keys("curPage"+"*"); redisTemplate.delete(keys); return userMapper.updateByPrimaryKey(user);下面这样不行的,当时一直很疑惑,只能更新第一页的缓存,后面页的进行add、delete、update后都没有更新。所有百度一下,换了这么的删除key的方法,是可以的。 edisTemplate.delete("curPage"+"*");//这样不行
上面代码的实现缓存并不是很好,缓存需要优雅的使用,并不是所有的项目都需要缓存技术,在使用缓存之前,需要确认你的项目是否真的需要缓存,使用缓存会引入一定的技术复杂度。笔者在这里只是在学习缓存技术时,学习过程中的一些思考与记录。 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |